/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package byzantine.views;

import att.grappa.Graph;
import att.grappa.Grappa;
import att.grappa.GrappaPanel;
import att.grappa.Parser;
import byzantine.ByzantineModel;
import byzantine.General;
import byzantine.GraphViz;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

/**
 *
 * @author rpathan
 */
public class TreeView extends JPanel implements View {

    //private int width;
    //private int height;
    private int width = 750;
    private int height = 525;
    ByzantineModel model;
    GraphViz graphViz;
    GrappaPanel graphPanel;
    private JScrollPane scrollPane;

    public TreeView(ByzantineModel model) {
        this.model = model;
        model.addObserver(this);
/*
        Toolkit t = Toolkit.getDefaultToolkit();
        Dimension screenSize = t.getScreenSize();
        width = (int)((screenSize.width - 10) * 0.55);
        height = (int)((screenSize.height - 100) * 0.88);
*/
        initializeView();
    }

    private void initializeView() {

        graphViz = new GraphViz();

        scrollPane = new JScrollPane();
        scrollPane.setPreferredSize(new Dimension(width, (int) (height * .99)));
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        scrollPane.setWheelScrollingEnabled(true);

        this.add(scrollPane);
        setBorder(BorderFactory.createEtchedBorder());
    }

    private void populateTree() {

        General selectedGeneral = model.getSelectedGeneral();
        if (model.isSimulationRunning()
                && model.getSelectedGeneral() != null
                && selectedGeneral.getType().equals(ByzantineModel.COMMANDER) == false
                && selectedGeneral.getType().equals(ByzantineModel.COMMANDER_REBEL) == false) {
            graphViz.readSource("unformatted_graph.dot");
            File formattedGraph = new File("formatted_graph.dot");
            graphViz.writeGraphToFile(graphViz.getGraph(graphViz.getDotSource(), "dot"), formattedGraph);

            try {
                InputStream input = new FileInputStream("formatted_graph.dot");

                Parser dotParser = new Parser(input, System.err);
                try {
                    dotParser.parse();
                } catch (Exception ex) {
                    System.err.println("Exception: " + ex.getMessage());
                    ex.printStackTrace(System.err);
                    System.exit(1);
                }
                Graph graph = dotParser.getGraph();

                graphPanel = new GrappaPanel(graph);
                // graphPanel.setScaleFactor(0.85);
                System.out.println("The graph contains " + graph.countOfElements(Grappa.NODE | Grappa.EDGE | Grappa.SUBGRAPH) + " elements.");
            } catch (FileNotFoundException e) {
                //e.printStackTrace(System.err);
            }
            scrollPane.setViewportView(graphPanel);
        } else {
            scrollPane.setViewportView(null);
        }
    }

    public void valueChanged() {
        if (model.hasSelectedGeneralChanged()
                || model.hasSimulationStatusChanged()
                || model.hasExaminedStepChanged()) {
            populateTree();
        }
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(width, height);
    }
}
